package pl.prv.polanie.client.widgets.schedule;

import java.util.ArrayList;
import java.util.List;

import pl.prv.polanie.client.Planner;
import pl.prv.polanie.client.dialogs.CreateSubjectEventDialog;
import pl.prv.polanie.client.dto.CSCalendarDayDTO;
import pl.prv.polanie.client.dto.CSGroupDTO;
import pl.prv.polanie.client.dto.CSPreferenceDTO;
import pl.prv.polanie.client.dto.CSSemesterDTO;
import pl.prv.polanie.client.dto.CSSemestersYearGroupsDTO;
import pl.prv.polanie.client.dto.CSSubjectEventDTO;
import pl.prv.polanie.client.dto.CSVCalendarDayDTO;
import pl.prv.polanie.client.dto.CSVSubjectEventDTO;
import pl.prv.polanie.client.model.Cache;
import pl.prv.polanie.client.model.CacheService;
import pl.prv.polanie.client.model.ContextSettings;
import pl.prv.polanie.client.model.ServiceHolder;
import pl.prv.polanie.client.model.UserSettings;
import pl.prv.polanie.client.model.ViewDataProvider;
import pl.prv.polanie.client.panels.SchedulesList;
import pl.prv.polanie.client.panels.lists.DeclarationsList;
import pl.prv.polanie.client.panels.lists.SubgroupsList;
import pl.prv.polanie.client.panels.lists.SubjectEventsList;
import pl.prv.polanie.client.panels.tabpanel.IMinimizableTabContent;
import pl.prv.polanie.client.widgets.CustomDialogBox;
import pl.prv.polanie.client.widgets.Loader;
import pl.prv.polanie.client.widgets.LoaderSizes;
import pl.prv.polanie.client.widgets.SelectBox;
import pl.prv.polanie.client.widgets.schedule.custom.SubjectEventEditionWidget;
import pl.prv.polanie.client.widgets.schedule.widgets.DraggableZone;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Kontrolka podzialu zajec.
 * 
 * 
 * 
 * @author Janusz Prokulewicz
 * Created: May 16, 2008
 */

public class Schedule extends Composite implements IMinimizableTabContent {
	
	//atrybuty filtra: semesterID 
	
//	//lecturerID
//	public static final int SCHEDULE_VIEW__LECTURER_PREFERENCES = 1;
//	//lecturerID
//	public static final int SCHEDULE_VIEW__LECTURER = 2;
//	//roomID
//	public static final int SCHEDULE_VIEW__ROOM = 3;
//	//groupID
//	public static final int SCHEDULE_VIEW__GROUP = 4;
	
	

	/** Rodzaj widoku podzialu zajec. Mozliwe wartosci powyzej.  */
	ScheduleView scheduleView; 
	
	long filterPropertyLecturerID = -1;
	long filterPropertySemesterID = -1;
	long filterPropertyGroupID = -1;
	long filterPropertyRoomID = -1;

	/**
	 * Wskazuje, czy widok jest jak dla studiow dziennych (true), czy jak dla studiow zaocznych (false).
	 */
	boolean fullTimeSchedule = true; 
	
	
	
	private static final String STYLE_SCHEDULE = "my-Schedule";
	private static final String STYLE_SCHEDULE_BORDER = "my-Schedule-Border";
	private static final String STYLE_SCHEDULE_HEADER = "my-Schedule-header";
	private static final String STYLE_SCHEDULE_FULLTIME_HOURS = "my-Schedule-fulltimeHours";
	private static final String STYLE_SCHEDULE_NOT_FULLTIME_HOURS = "my-Schedule-notFulltimeHours";
	
	private static final String STYLE_SCHEDULE_PRINTOUT_SCHEDULE_REPORT = "my-Schedule-printoutScheduleReport";

	private static final String STYLE_SCHEDULE_HIDDEN_IN_PRINT = "my-Schedule-HiddenInPrint";
	private static final String STYLE_SCHEDULE_DISPLAYED_IN_PRINT = "my-Schedule-DisplayedInPrint";
	
	private static final String STYLE_HIDDEN = "hidden";
	
	
	private Loader loader = null;
	
	
	
	
	/** glowna kontrolka kalendarza */
	private AbsolutePanel mainAP = new AbsolutePanel();
	/** koszyk z eventami nieprzyporzadkowanymi do konkretnego dnia w podziale */
//	private DraggableZone subjectEventsCart = new DraggableZone(true);

	
	//TODO tutaj
	
//	private TableSubjectEvents subjectEventsTable = new TableSubjectEvents(null) {
////		@Override
//		protected void runOnHighlightingRow(ICSVDTO csvDto) {
//			super.runOnHighlightingRow(csvDto);
//			highlightSubjectEventByID(csvDto.getId());
//		}
//	};
	private SubjectEventsList subjectEventsList = new SubjectEventsList(this);
	
//	private HTML createNewSubjectEventHTML = new HTML("create new subject event");
	
	
	//
	private SubjectEvent highlightedSubjectEvent = null;
	private SubjectEvent selectedSubjectEvent = null;
	
	
	//kontrolka do wlaczania/wylacznia podpowiedzi
//	private DialogBox seEditionWidgetDialogBox = null;
	private SubjectEventEditionWidget seEditionWidget =  null;
	
	
	/** Tworzony lub edytowany (takze przenoszony) lecturerPreferences. */
	private LecturerPreferences activeLecturerPreferences = null;
	
	
	
	private boolean areShownSubjectEventsHintsForLecturer = false;
	private boolean areShownSubjectEventsHintsForRoom = false;
	
	private boolean areShownLecturerPreferences = false;
	
	
	private boolean seEditionWidgetShowedBeforeMinimize = false;
	
	private boolean displayHintsWidgetDuringSEEdition = true;
	
	/** */
	private boolean areShownLocationsForSubjectEvents = false;
	/** wskazuje, czy pokazane sa subjectEventsy spoza wyswietlanego podzialu. */
	private boolean areShownSubjectEventHints = false;
	
//	private SimplePanel outerSP = new SimplePanel();
	private VerticalPanel borderVP = new VerticalPanel(){
		public void onBrowserEvent(Event event) {
			super.onBrowserEvent(event);
			switch (DOM.eventGetType(event)) {
//			case Event.ONCLICK:
//				GWT.log("ONCLICK", null);
//				break;
			case Event.ONMOUSEUP:
				if (DOM.eventGetButton(event) == Event.BUTTON_RIGHT) {
					runOnRightClick();
				}
				break;
			default:
				break;
			}
		}
	};
	
	
	
	
	
	//etykieta z infromacja o semestrze
	private HorizontalPanel headerLabelHP = new HorizontalPanel();
	
	private HTML headerGroupNameLabel = new HTML("<center>title</center>");
	private HTML headerRefreshLink = new HTML("<span class='plan-Link'>Refresh</span></center>");
	
	private HorizontalPanel lectHP = new HorizontalPanel();
	private HTML toggleLecturerPreferencesViewLink = new HTML("<span class='plan-Link'>Show Lecturer Preferences</span></center>");
	  
	private HTML headerLabel1 = new HTML("");

	
	private HTML headerLabelSubgroups = new HTML("<span class='plan-Link'>Subgroups</span></center>");
	private HTML headerLabelDeclarations = new HTML("<span class='plan-Link'>Declarations</span></center>");
	private HTML headerLabelHints = new HTML("<span class='plan-Link'>Hints</span></center>");

	//etykieta "soboty" - tylko dla zaocznych
	private HTML headerLabel2 = new HTML("<center>Saturdays</center>");
	//etykieta "niedziele" - tylko dla zaocznych
	private HTML headerLabel3 = new HTML("<center>Sundays</center>");
	
	
	private HTML hoursHTML1 = new HTML("");
	private HTML hoursHTML2 = new HTML("");
	
	/** list of Day objects */
	private List<Day> calendarDays = new ArrayList<Day>();
	
	private PrintoutScheduleReport printoutScheduleReport = new PrintoutScheduleReport();
	
	
	public Schedule(boolean fullTimeSchedule, ScheduleView scheduleView) {
		this.scheduleView = scheduleView;
		this.fullTimeSchedule = fullTimeSchedule;
		setupHeaderLabels();
		setupHoursHTML();
		
		setupMainAP();
		setupSubjectEventsCart();
		
		borderVP.setStyleName(STYLE_SCHEDULE_BORDER);
		borderVP.add(mainAP);
		
//		borderVP.add(subjectEventsCart);
//		subjectEventsCart.setParentSchedule(this);
//		borderVP.add(subjectEventsTable);
		
		subjectEventsList.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
		printoutScheduleReport.addStyleName(STYLE_SCHEDULE_DISPLAYED_IN_PRINT);
		printoutScheduleReport.addStyleName(STYLE_SCHEDULE_PRINTOUT_SCHEDULE_REPORT);
		
		borderVP.add(subjectEventsList);
		
		
		borderVP.add(printoutScheduleReport);
		
		
//		createNewSubjectEventHTML.addStyleName("link");
//		createNewSubjectEventHTML.addClickListener(new ClickListener() {
//			public void onClick(Widget sender) {
//				Planner.log(".Schedule: " + "");
//				CreateSubjectEventDialog csed = new CreateSubjectEventDialog(Schedule.this, null, null);
//				csed.center();
////				csed.set
//			}
//		});
//		
//		borderVP.add(createNewSubjectEventHTML);
		
		
//		Button b = new Button("clean LP");
//		b.addClickListener(new ClickListener() {
//			public void onClick(Widget sender) {
//				Schedule.this.hideLecturerPreferences();
//			}
//		});
//		borderVP.add(b);
		initWidget(borderVP);
		
		DOM.sinkEvents(borderVP.getElement(), Event.ONMOUSEUP);
//		fillScheduleWithData();
		
//		addDays();
		
	}
	
//	public Schedule(boolean loadExampleData) {
//		this();
//		
//		if (loadExampleData) {
////			fillScheduleWithData();
//		}
//	}
	

	public void setHeaderText(String text) {
		headerGroupNameLabel.setHTML("<center>" + text + "");		
	}
	
	
	private void setupHeaderLabels() {
		headerLabelHP.setSpacing(3);
		headerLabelHP.add(headerRefreshLink);
		headerRefreshLink.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
		if (isScheduleViewGroup()) {
			if (ContextSettings.isAdminUserSignedIn()) {
				headerLabelSubgroups.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
				headerLabelHP.add(headerLabelSubgroups);
				headerLabelDeclarations.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
				headerLabelHP.add(headerLabelDeclarations);
			}
			
			headerLabelHints.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
			headerLabelHints.addStyleName(STYLE_HIDDEN);
			headerLabelHP.add(headerLabelHints);
		}
		
		headerLabel1.setStyleName(STYLE_SCHEDULE_HEADER);
		headerLabel1.setHeight("20px");
//		headerLabel1.setWidth(1055 + "px");
		
		headerRefreshLink.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				reloadSchedule();
			}
		});
		
		if (isScheduleViewConnectedWithLecturer() && ContextSettings.isAdminUserSignedIn()) {
			Planner.log("Schedule.setupHeaderLabels: " + "TAJ, JEST CONNE LECT");
			toggleLecturerPreferencesViewLink.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
			toggleLecturerPreferencesViewLink.addClickListener(new ClickListener() {
				public void onClick(Widget sender) {
					if (scheduleView == ScheduleView.LECTURER) {
						
						removeAllSubectEvents();
						markAsLoading();
//						Planner.fadeWidgetWithMsg("Loading lecturer preferences...", Schedule.this);
						
						toggleLecturerPreferencesViewLink.setHTML("<span class='plan-Link'>Show Lecturer Events</span></center>");
						scheduleView = ScheduleView.LECTURER_PREFERENCES;
						SchedulesList.downloadCSLecturerPreferences(Schedule.this,
								new Long(filterPropertyLecturerID), new Long(filterPropertySemesterID));
						
					} else if (scheduleView == ScheduleView.LECTURER_PREFERENCES) {
						
						hideLecturerPreferences();
						markAsLoading();
						toggleLecturerPreferencesViewLink.setHTML("<span class='plan-Link'>Show Lecturer Preferences</span></center>");
						scheduleView = ScheduleView.LECTURER;
						
						SchedulesList.downloadCSSubjectEvents(Schedule.this,
								null, null, new Long(filterPropertyLecturerID), null);
						
					}
				}
			});

			lectHP.setSpacing(3);
			lectHP.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
			lectHP.add(toggleLecturerPreferencesViewLink);
		}
		
		
		if (isScheduleViewGroup()) {
			headerLabelSubgroups.addClickListener(new ClickListener() {
				public void onClick(Widget sender) {
					CustomDialogBox db = new CustomDialogBox(false, true);
					db.setText("Subgroups");
					db.setWidget(new SubgroupsList(filterPropertyGroupID));
					db.center();
				}
			});
			
			headerLabelDeclarations.addClickListener(new ClickListener() {
				public void onClick(Widget sender) {
					CustomDialogBox db = new CustomDialogBox(false, true);
					db.setText("Declarations");
					db.setWidget(new DeclarationsList(Schedule.this, filterPropertyGroupID));
					db.center();
				}
			});
			
			headerLabelHints.addClickListener(new ClickListener() {
				public void onClick(Widget sender) {
					displayHintsWidgetDuringSEEdition = true;
					showSubjectEventEditionWidget(selectedSubjectEvent);
				}
			});
		}
		
		
		if (!fullTimeSchedule) {
			headerLabel2.setStyleName(STYLE_SCHEDULE_HEADER);
			headerLabel2.setHeight("20px");
			headerLabel2.setWidth(1055 + "px");
			
			
			headerLabel3.setStyleName(STYLE_SCHEDULE_HEADER);
			headerLabel3.setHeight("20px");
			headerLabel3.setWidth(1055 + "px");
		}
		
	}

	
	private void setupHoursHTML() {
		hoursHTML1.setWidth("50px");
		if (fullTimeSchedule) {
			hoursHTML1.setStyleName(STYLE_SCHEDULE_FULLTIME_HOURS);
			hoursHTML1.setHeight("561px");
		} else {
			hoursHTML1.setStyleName(STYLE_SCHEDULE_NOT_FULLTIME_HOURS);
			hoursHTML1.setHeight("271px");
			
			hoursHTML2.setStyleName(STYLE_SCHEDULE_NOT_FULLTIME_HOURS);
			hoursHTML2.setWidth("50px");
			hoursHTML2.setHeight("271px");
		}
	}
	
	
	private void setupSubjectEventsCart() {
//		subjectEventsCart.setWidth("800px");
//		subjectEventsCart.setHeight("150px");
	}
	
	
	private void setupMainAP() {
		mainAP.setStyleName(STYLE_SCHEDULE);
		
		mainAP.setWidth("1055px");
		
		int mainAPHeight = 584;
		if (!fullTimeSchedule) {
			mainAPHeight = 642;
		}
		
		mainAP.setHeight(mainAPHeight+"px");
		
		mainAP.add(headerLabel1,0,0);
		mainAP.add(headerGroupNameLabel, 0, 0);

		
		int left = mainAP.getWidgetLeft(headerLabel1);
		mainAP.add(headerLabelHP, left, 0);
		
		
		
		if (!fullTimeSchedule) {
			mainAP.add(headerLabel2, 0, 20);
			mainAP.add(headerLabel3, 0, 331);
		}
		
		
		if (fullTimeSchedule) {
			mainAP.add(hoursHTML1,0,20);
		} else {
			mainAP.add(hoursHTML1, 0, 60);
			mainAP.add(hoursHTML2, 0, 371);
		}
		
		if (isScheduleViewConnectedWithLecturer()) {
			mainAP.add(lectHP, 1, 0);
		}
//		
//		if (fullTimeSchedule) {
//			mainAP.add(hoursHTML2);
//			
//		}
	}
	
	
	
	public void fixLabelsPositionsAfterAddingNewDay() {
		//ustawiamy poprawna szerosc (zeby byly widoczne wszystkie dni)
		int rightBorder = getPositionOfRightBorderOfLastDayInCalendar();
		mainAP.setWidth(rightBorder + "px");
		headerLabel1.setWidth(rightBorder + "px");
		
		if (!fullTimeSchedule) {
			headerLabel2.setWidth(rightBorder + "px");
			headerLabel3.setWidth(rightBorder + "px");
		}
		
		//ustawiamy kontrolki
		int positionForGroupNameLabel = calculatePositionForGroupLabel(rightBorder);
//		Planner.log("Schedule.fixLabelsPositionsAfterAddingNewDay: " + "XXXXXXXXXXXXXXXXXX " + positionForGroupNameLabel);
		mainAP.setWidgetPosition(headerGroupNameLabel, positionForGroupNameLabel, 0);
		mainAP.setWidgetPosition(headerLabelHP, positionForGroupNameLabel + headerGroupNameLabel.getOffsetWidth() + 5, 0);
		
		Widget parentW = getParent();
//		Planner.log("Schedule.fixLabelsPositionsAfterAddingNewDay: " + " SET WIDTH NA WRAPPER " + rightBorder);
		parentW.setWidth(rightBorder + "px");
	}
	
	/**
	 * Oblicza pozycje kontrolki z nazwa grupy w tytule planu, 
	 * @return
	 */
	private int calculatePositionForGroupLabel(int rightBorder) {
		if (rightBorder == 0) {
//			Planner.log("Schedule.calculatePositionForGroupLabel: " + "YYYYYYYYYYYYYYYYYYYYYYYY rightBorder: " + rightBorder);

			rightBorder = getPositionOfRightBorderOfLastDayInCalendar();
		}
//		Planner.log("Schedule.fixLabelsPositionsAfterAddingNewDay: " + rightBorder);

		int headerWidth = headerGroupNameLabel.getOffsetWidth();
//		Planner.log("Schedule.calculatePositionForGroupLabel: " + "YYYYYYYYYYYYYYYYYYYYYYYY rightBorder: " + rightBorder + ", headerWidth " + headerWidth);
		
		double result = rightBorder/2.0 - 0.5 * headerWidth;
//		Planner.log("Schedule.calculatePositionForGroupLabel: " + "YYYYYYYYYYYYYYYYYYYYYYYY " + result);
		return (int)result;
	}
	
	
	
	/**
	 * Zwraca polozenie prawej granicy najbardziej wysunietego na prawo dnia w podziale.
	 * @return
	 */
	private int getPositionOfRightBorderOfLastDayInCalendar() {

		int maxRight = 0;
		
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = calendarDays.get(i);
			
			if (d.getParent().equals(mainAP)) {
				maxRight = mainAP.getWidgetLeft(d) + d.getOffsetWidth();
			}
		}
		
		return maxRight;
	}
	

	
	public void addCalendarDay(CSCalendarDayDTO dto, CSVCalendarDayDTO csvDto) {
		boolean fullTimeView = CacheService.isFullTimeSemesterSelected();
		
//		if (fullTimeView) {
			Day d = new Day(dto, csvDto, fullTimeView);
			d.setParentSchedule(this);
			
			int dayNo = 0;
			if (fullTimeView) {
				dayNo = getPreviouslyAddedAllDays();
			} else if (dto.isSunday()) {
				dayNo = getPreviouslyAddedSundays();
			} else if (!dto.isSunday()) {
				dayNo = getPreviouslyAddedSaturdays();
			}
			
			int calendarDayWidth = 201;
			if (!fullTimeView) {
				calendarDayWidth = 70;
			}
			
			int left = 50 + dayNo * calendarDayWidth;
			calendarDays.add(d);
			
			int top = 20;
			if (!fullTimeSchedule) {
				
				if (dto.isSunday()) {
					top  = 351;
				} else {
					top = 40;
				}
			}
//		} else {
//			
//			
//			
//			
//		}
//		
		
		mainAP.add(d, left, top);
	}
	
	
	/**
	 * Zwraca liczbe dodanych wczesniej dni, ktore beda na formatce w tym samym wierszu.
	 * Dla fullTimeSchedule, bedzie to liczba rowna liczbie wszystkich dodanych wczesniej dni,
	 * a dla widoku zaocznego bedzie to liczba dodanych wczesniej sobot/niedziel. 
	 * @return
	 */
	private int getPreviouslyAddedSundays() {
		int counter = 0;
		for (int i = 0; i < calendarDays.size(); i++) {
			Day day = calendarDays.get(i);
			CSCalendarDayDTO csCD = day.getCalendarDayDTO();
			
			if (csCD.isSunday()) {
				counter++;
			}
		}
		return counter;
	}
	
	private int getPreviouslyAddedSaturdays() {
		int counter = 0;
		for (int i = 0; i < calendarDays.size(); i++) {
			Day day = calendarDays.get(i);
			CSCalendarDayDTO csCD = day.getCalendarDayDTO();
			
			if (!csCD.isSunday()) {
				counter++;
			}
		}
		return counter;
	}
	
	private int getPreviouslyAddedAllDays() {
		return calendarDays.size();
	}


	
	
	
	
	public static boolean isFullTimeView(CSGroupDTO csDto) {
		long sygID = csDto.getSemestersYearGroupID();
		CSSemestersYearGroupsDTO csSYG = Cache.getCSSemestersYearGroupsDTOByID(sygID);
		long semesterID = csSYG.getSemesterID();
		
		CSSemesterDTO semesterDTO = Cache.getCSSemesterDTOByID(semesterID);
		long studiesTypeID = semesterDTO.getStudiesTypeID();
		
		if (studiesTypeID == 1 || studiesTypeID == 3) {
			return true;
		}
		
		return false;
	}
	
	
	public void removeCSSubjectEvent(CSSubjectEventDTO dto) {

		long seID = dto.getId();
		
		
		//w callu
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			
			d.removeSubjectEventByID(seID);

			
			
//			if ( d.getCalendarDayDTO().getId() == dto.getCalendarDayID() ) {
//				
//				
//				//w przypadku edycji istniejacego SE (np zmiany dnia), potrzeba odswiezyc dzien, w ktorym SE byl poprzednio
////					long toRefreshCalendarDayID = -1;
//				SubjectEvent seToRemove = getSubjectEventByID(dto.getId());
//				if (seToRemove != null) {
////						toRefreshCalendarDayID = seToRemove.getSubjectEventDTO().getCalendarDayID();
//					Day toRefreshCalendarDay = seToRemove.getParentDay();
//					Planner.log("Schedule.addCSSubjectEvent: " + "odswiezenie dnia, w ktorym SE znajdowalo sie przed zmiana, id: " + toRefreshCalendarDay.getCalendarDayDTO().getId());
//					seToRemove.removeFromParent();
//					//TODO odswiezyc dzien
//				}
//
//				
//				
//				//TABELA
//				CSVSubjectEventDTO csvSE = ViewDataProvider.getCSVSubjectEvent(dto);
////					subjectEventsTable.addRow(dto, csvSE);
//				subjectEventsTable.saveOrUpdateSubjectEventInTable(dto);
//				
//				SubjectEvent e = new SubjectEvent(dto, csvSE);
//				GWT.log("Schedule.addSubjectEvent dodaje do dnia, id: " + d.getCalendarDayDTO().getId(), null);
//				
//				
//				
//				d.addEvent(e);
//				
//				for (int j = 0; j < calendarDays.size(); j++) {
//					e.addDraggingListener( ((Day)calendarDays.get(j)).getEventsDZ() );
//				}
////					e.addDraggingListener(subjectEventsCart);
//				
//				return;
//				//e.addDraggingListener( d.getEventsDZ() );
//			}
		}
		
		
		
		
		
		
		
		
		
		
		
		
		// przeszukac podzial i usunac SubjectEvent
		// usunac z tabeli
		
		
		
	}
	
	
	
	
	
	/**
	 * Dodaje nowy subject event do podzialu (lub koszyka na nieprzydzielone subjectEventy, <br>
	 * gdy w podanym DTO nie ma ustawionego calendarDay)
	 * @param dto
	 */
	public void addCSSubjectEvent(CSSubjectEventDTO dto) {
		
		if (dto.getCalendarDayID() != -1) {
			for (int i = 0; i < calendarDays.size(); i++) {
				Day d = (Day)calendarDays.get(i);
				if ( d.getCalendarDayDTO().getId() == dto.getCalendarDayID() ) {
					
					
					//w przypadku edycji istniejacego SE (np zmiany dnia), potrzeba odswiezyc dzien, w ktorym SE byl poprzednio
//					long toRefreshCalendarDayID = -1;
					SubjectEvent seToRemove = getSubjectEventByID(dto.getId());
					if (seToRemove != null) {
//						toRefreshCalendarDayID = seToRemove.getSubjectEventDTO().getCalendarDayID();
						Day toRefreshCalendarDay = seToRemove.getParentDay();
						Planner.log("Schedule.addCSSubjectEvent: " + "odswiezenie dnia, w ktorym SE znajdowalo sie przed zmiana, id: " + toRefreshCalendarDay.getCalendarDayDTO().getId());
						seToRemove.removeFromParent();
						//TODO odswiezyc dzien
					}

					
				
					//TABELA
//					Planner.log("Schedule.addCSSubjectEvent: " + "!!!!!!!!!!!!!!!!!!!!! " + dto);
					CSVSubjectEventDTO csvSE = ViewDataProvider.getCSVSubjectEvent(dto);
					
//					subjectEventsTable.addRow(dto, csvSE);
					subjectEventsList.getTableSubjectEvents().saveOrUpdateSubjectEventInTable(dto);
					
					SubjectEvent e = new SubjectEvent(dto, csvSE);
					addSubjectEventToDay(d, e);
					
					return;
					//e.addDraggingListener( d.getEventsDZ() );
				}
			}
		}
		
		
//		Planner.log("Schedule.addCSSubjectEvent: " + "nie znalazlem dnia");
		
		//ponizszy kod bedzie wykonany, gdy dodajemy subjectEventa jeszcze nie umieszczonego w podziale zajec
//		CSVSubjectEventDTO csvSE = ViewDataProvider.getCSVSubjectEvent(dto);
		subjectEventsList.getTableSubjectEvents().saveOrUpdateSubjectEventInTable(dto);
//		subjectEventsTable.addRow(dto, csvSE);

		
		//kod zakomentowany po wycofaniu koszyka
//		//ponizszy kod bedzie wykonany wtedy, gdy dodajemy subjectEvent do koszyka
//		SubjectEvent e = new SubjectEvent(dto, null);
////		GWT.log("Schedule.addSubjectEvent dodaje do kossyka", null);
//		subjectEventsCart.add(e);
//		
//		//podpiecie listenerow
//		for (int j = 0; j < calendarDays.size(); j++) {
//			e.addDraggingListener( ((Day)calendarDays.get(j)).getEventsDZ() );
//		}
//		e.addDraggingListener(subjectEventsCart);
	}

	/**
	 * Ddoaje kontrolke SubjectEvent do podzialu pod wskazany dzien.
	 * @param d
	 * @param e
	 */
	public void addSubjectEventToDay(Day d, SubjectEvent e) {
//		Planner.log("Schedule.addSubjectEvent dodaje do dnia, id: " + d.getCalendarDayDTO().getId());
		
		d.addEvent(e, CacheService.isFullTimeSemesterSelected());
		
		for (int j = 0; j < calendarDays.size(); j++) {
			e.addDraggingListener( ((Day)calendarDays.get(j)).getEventsDZ() );
		}
	}
	
	public SubjectEvent getSubjectEventByID(long id) {
		
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			
			SubjectEvent se = d.getSubjectEventByID(id);
			if (se != null) {
				return se;
			}
			
		}

//		Planner.log("Schedule.getSubjectEventByID: " + "nie znaleziono SE o id " + id);
		return null;
	}	
	
	public void addSubjectEvent(CSSubjectEventDTO dto, CSVSubjectEventDTO csvDto) {
//		GWT.log("poczatek " + dto.toLabel(), null);
		
		if (dto.getCalendarDayID() != 0) {
			for (int i = 0; i < calendarDays.size(); i++) {
				Day d = (Day)calendarDays.get(i);
				if ( d.getCalendarDayDTO().getId() == dto.getCalendarDayID() ) {
					SubjectEvent e = new SubjectEvent(dto, csvDto);
					addSubjectEventToDay(d, e);
					
					return;
					//e.addDraggingListener( d.getEventsDZ() );
				}
			}
		}
		
//		//ponizszy kod bedzie wykonany wtedy, gdy dodajemy subjectEvent do koszyka
//		SubjectEvent e = new SubjectEvent(dto, csvDto);
////		GWT.log("Schedule.addSubjectEvent dodaje do kossyka", null);
//		subjectEventsCart.add(e);
//		
//		//podpiecie listenerow
//		for (int j = 0; j < calendarDays.size(); j++) {
//			e.addDraggingListener( ((Day)calendarDays.get(j)).getEventsDZ() );
//		}
//		e.addDraggingListener(subjectEventsCart);
	}
	
	/**
	 * Dodaje subjectEventHint (subject event podpowiadajacy) do podzialu<br>
	 * @param selectedDTO - dto, popdpiete do SE, który został klikniety w kontrolce Schedule.
	 * @param hintDTO - dto, na podstawie ktorego zostanie wykreowany hint
	 */
	public void addCSSubjectEventHint(CSSubjectEventDTO selectedDTO, CSSubjectEventDTO hintDTO, int hintSort) {
//		GWT.log("poczatek " + dto.toLabel(), null);
//		areShownSubjectEventHints = true;
		
		
		if (hintDTO.getCalendarDayID() != 0) {
			
			Day d = getDayWithGivenCalendarDayID(hintDTO.getCalendarDayID());
			
			if (d != null) {
				//jesli hint ma inne id niz zaznaczony SE w Schedule,
				//to dodajemy go
				if (selectedDTO.getId() != hintDTO.getId()) {
					
					SubjectEventHint seh = new SubjectEventHint(hintDTO, hintSort);
					
					
					
					SubjectEvent se = d.getSubjectEventByID(hintDTO.getId());
					if (se != null) {
						int left = d.getSubjectEventWidgetLeft(se);
						int top = d.getSubjectEventWidgetTop(se);
						int width = se.getOffsetWidth();
						int height = se.getOffsetHeight();
						
						d.addSubjectEventHint(seh, left, top, width, height);
					} else {
						d.addSubjectEventHint(seh);
					}
					
//					Planner.log("Schedule.addSubjectEventHint dodaje do dnia, id: " + d.getCalendarDayDTO().getId());
				}
				
				
				return;
			}
			
		}
	}
	
	
	private Day getDayWithGivenCalendarDayID(long calendarDayID) {
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = calendarDays.get(i);
			if ( d.getCalendarDayDTO().getId() == calendarDayID ) {
				return d; 
			}
		}
		return null;
	}
	
	
	public LecturerPreferences addCSPreferences(CSPreferenceDTO dto) {

		if (dto.getCalendarDayID() != 0) {
			for (int i = 0; i < calendarDays.size(); i++) {
				Day d = (Day)calendarDays.get(i);
				
//				Planner.log("PLAMA " + d.getCalendarDayDTO().getId());
				
				if ( d.getCalendarDayDTO().getId() == dto.getCalendarDayID() ) {
//					Planner.log("Schedule addCSPreferences() znalazlem dzien o wskazanym id = " + dto.getCalendarDayID());
					
					int width = 200;
					if (!fullTimeSchedule) {
						width = 70;
					}
					
					LecturerPreferences lp = new LecturerPreferences(dto, width, scheduleView);
					d.addLecturerPreferences(lp);
					
					for (int j = 0; j < calendarDays.size(); j++) {
						lp.addDraggingListener( ((Day)calendarDays.get(j)).getEventsDZ() );
					}
					
					return lp;
				}
			}
		}
		
		return null;
	}

	/**
	 * Chowa wszystkie wczytane LecturerPreferences.
	 */
	public void hideLecturerPreferences() {
		
		if (areShownLecturerPreferences) {
			areShownLecturerPreferences = false;
			
			for (int i = 0; i < calendarDays.size(); i++) {
				Day d = (Day)calendarDays.get(i);
				DraggableZone dz = d.getEventsDZ();
				for (int j = dz.getWidgetCount()-1; j > 0; j--) {
					Widget w = dz.getWidget(j);
					if (w instanceof LecturerPreferences) {
						LecturerPreferences lp = (LecturerPreferences) w;
						dz.remove(j);
					}
				}
			}
		}
	}
	
	/**
	 * Chowa SubjectEventHint'y, ktore sa podanego rodzaju. Jesli hintSort == SubjectEventHint.HINT_SORT__NOT_SPECIFIED,
	 * usunie wszystkie subjectEventHint'y.
	 * @param hintSort - rodzaj seHintow, ktore zostana usuniete
	 */
	public void hideSubjectEventsHints(final int hintSort) {
		
//		areShownSubjectEventHints = false;
		if (hintSort == SubjectEventHint.HINT_SORT__NOT_SPECIFIED) {
			areShownSubjectEventsHintsForLecturer = false;
			areShownSubjectEventsHintsForRoom = false;
		} else if (hintSort == SubjectEventHint.HINT_SORT__LECTURER) {
			areShownSubjectEventsHintsForLecturer = false;
		} else if (hintSort == SubjectEventHint.HINT_SORT__ROOM) {
			areShownSubjectEventsHintsForRoom = false;
		}
		
		
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();
			for (int j = dz.getWidgetCount()-1; j >= 0; j--) {
				Widget w = dz.getWidget(j);
				if (w instanceof SubjectEventHint) {
					SubjectEventHint lp = (SubjectEventHint) w;
					if (hintSort == SubjectEventHint.HINT_SORT__NOT_SPECIFIED || lp.getHintSort() == hintSort) {
						Planner.log("Schedule.hideSubjectEventsHints() usuwam z widoku seHint ");
						dz.remove(j);
					}
				}
			}
		}
	}
	
	/**
	 * Usuwa wszystkie subjectEventHinty z podzialu.
	 */
	public void hideSubjectEventsHints() {
		hideSubjectEventsHints(SubjectEventHint.HINT_SORT__NOT_SPECIFIED);
	}
		
	
	public void toggleLocationsForSubjectEvents() {
		if (areShownLocationsForSubjectEvents) {
			hideLocationsForSubjectEvents();
		} else {
			showLocationsForSubjectEvents();
		} 
	}
	
	
	public void toggleSubjectEventsHints() {
		if (areShownSubjectEventHints) {
			hideSubjectEventsHints();
		} else {
			
		}
	}
	
	public void hideLocationsForSubjectEvents() {
		areShownLocationsForSubjectEvents = false;
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();
			for (int j = dz.getWidgetCount()-1;  j >= 0; j--) {
				Widget w = dz.getWidget(j);
				if (w instanceof LocationForSubjectEvent) {
					LocationForSubjectEvent lfse = (LocationForSubjectEvent) w;
					dz.remove(lfse);
				}
			}
		}
	}

	public void showLocationsForSubjectEvents() {
		areShownLocationsForSubjectEvents = true;
		
		for (int i = 0; i < calendarDays.size(); i++) {
			
			//dzien
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();

			List<PeriodOfTime> periodsOfTimeList = new ArrayList<PeriodOfTime>();
			
			

			
			for (int j = dz.getWidgetCount()-1;  j >= 0; j--) {
				Widget w = dz.getWidget(j);
				if (w instanceof SubjectEvent) {
					SubjectEvent se = (SubjectEvent)w;
					CSSubjectEventDTO csDto = se.getSubjectEventDTO();
					PeriodOfTime pot = new PeriodOfTime(csDto.getStartTime().longValue(), csDto.getDuration().longValue());
					
					periodsOfTimeList.add(pot);
				}
			}
			
			
			//listowanie
			for (int j = 0; j < periodsOfTimeList.size(); j++) {
				PeriodOfTime pot = (PeriodOfTime)periodsOfTimeList.get(j);
//				Planner.log("Schedule.showLocationsForSubjectEvents: przed merge " + j + ": st " + pot.getStartTime() + ", d " + pot.getDuration());
			}
			
			
			//
			PeriodOfTime[] pots = (PeriodOfTime[])periodsOfTimeList.toArray(new PeriodOfTime[0]);
			PeriodOfTime[] mergedPots = PeriodOfTime.mergePeriodsOfTime(pots);
			
			
			//listowanie po
			for (int j = 0; j < mergedPots.length; j++) {
				PeriodOfTime pot = mergedPots[j];
//				Planner.log("Schedule.showLocationsForSubjectEvents: po merge " + j + ": st " + pot.getStartTime() + ", d " + pot.getDuration());
				
				LocationForSubjectEvent lfse = new LocationForSubjectEvent(pot);
				d.addLocationForSubjectEvent(lfse);
			}
			
		}
	}
	
//	protected void onAttach() {
//		super.onAttach();
//		
//		for (int i = 0; i < days.size(); i++) {
//			Day d = (Day)days.get(i);
//			AbsolutePanel dz = d.getEventsDZ();
//			for (int j = 0; j < dz.getWidgetCount(); j++) {
//				Event e = (Event)dz.getWidget(j);
//				e.setOffsetWidth(dz.getOffsetWidth());
//				e.setOffsetHeight(54);
//				
//			}
//		}
//	}
	
	
//	private void addDays() {
//		for (int i = 0; i < 5; i++) {
//			addDay(i);
//		}
//
//		Event[] events = new Event[10];
//		
//		for (int i = 0; i < events.length; i++) {
//			events[i] = new Event("ZAJECIA " + i);
//		}
//		
//		Event event= new Event("ZAJECIA");
//		Event event2= new Event("ZAJECIA");
//		
//		for (int i = 0; i < days.size(); i++) {
//			event.addDraggingListener( ((Day)days.get(i)).getEventsDZ() );
//			event2.addDraggingListener( ((Day)days.get(i)).getEventsDZ() );
//		}
//		((Day)days.get(0)).getEventsDZ().add(event);
//		((Day)days.get(1)).getEventsDZ().add(event2);
//	}
	
	
//	/**
//	 * Generuje piec dayDTO i wrzuca do podzialu.<br>
//	 * Generuje 10 eventDTO i wrzuca do podzialu. 
//	 */
//	private void fillScheduleWithData() {
//		for (int i = 0; i < 5; i++) {
//			DayDTO d = new DayDTO(i);
//			addDay(d);
//		}
//		
//		for (int i = 0; i < 10; i++) {
//			EventDTO e = new EventDTO(i, i/2 + 0);
//			addEvent(e);
//		}
//		
////		EventDTO e = new EventDTO();
//	}
	
	public void saveOrUpdateSubjectEventInTable(CSSubjectEventDTO csDto) {
		subjectEventsList.getTableSubjectEvents().saveOrUpdateSubjectEventInTable(csDto);
	}
	
	
	
	/**
	 * Podswietla jeden SE o podanym id, na formatce podzialu zajec. 
	 * @param id
	 */
	public void highlightSubjectEventByID(long id) {
		
//		Planner.log("Schedule.highlightSubjectEventByID: " + "podswietlam SE o id " + id);
		
		if (highlightedSubjectEvent != null) {
			highlightedSubjectEvent.removeHighlighting();
		}
		
		for (int i = 0; i < calendarDays.size(); i++) {
			
			//dzien
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();
			
			for (int j = 0; j < dz.getWidgetCount(); j++) {
				Widget w = dz.getWidget(j);
				if (w instanceof SubjectEvent) {
					SubjectEvent se = (SubjectEvent)w;
					CSSubjectEventDTO csDto = se.getSubjectEventDTO();
					if (csDto.getId() == id) {
						se.highlightSubjectEvent();
						highlightedSubjectEvent = se;
						return;
					}
				}
			}
		}
	}
	
	/**
	 * Podswietla na niebiesko jeden SE o podanym id, na formatce podzialu zajec. 
	 * @param id
	 */
	public void setSelectedSubjectEventByID(long id) {
		
//		Planner.log("Schedule.setSelectedSubjectEventByID: " + "wybieram SE o id " + id);
		
		if (selectedSubjectEvent != null) {
			selectedSubjectEvent.removeSelection();
		}
		
		for (int i = 0; i < calendarDays.size(); i++) {
			
			//dzien
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();
			
			for (int j = 0; j < dz.getWidgetCount(); j++) {
				Widget w = dz.getWidget(j);
				if (w instanceof SubjectEvent) {
					SubjectEvent se = (SubjectEvent)w;
					CSSubjectEventDTO csDto = se.getSubjectEventDTO();
					if (csDto.getId() == id) {
						se.selectSubjectEvent();
						selectedSubjectEvent = se;
						return;
					}
				}
			}
		}
	}

	/**
	 * Jesli jakis SE jest zaznaczony, to odznacza go. 
	 */
	public void cleanSubjectEventSelection() {
		if (selectedSubjectEvent != null) {
			selectedSubjectEvent.removeSelection();
			selectedSubjectEvent = null;
		}
	}
	
	/**
	 * Jesli jakis SE jest zaznaczony, to odznacza go.
	 */
	public void cleanSubjectEventSelectionInTable() {
		subjectEventsList.getTableSubjectEvents().removeSelectionFromRow();
	}
	
	
	
	/**
	 * Podswietla jeden SE o podanym id, w kontrolce tabeli z SubjectEventami. 
	 * @param id
	 */
	public void highlightSubjectEventInTableByID(long id) {
		
//		Planner.log("Schedule.highlightSubjectEventInTableByID(): " + "podswietlam SE o id " + id);
		
		subjectEventsList.getTableSubjectEvents().highlightRowByID(id);
	}
	
	/**
	 * Usuwa podswietlenie z SE (jesli jakis jest podswietlony)
	 */
	public void removeHighlightingFromSubjectEvent() {
		if (highlightedSubjectEvent != null) {
			highlightedSubjectEvent.removeHighlighting();
		}
		
		subjectEventsList.getTableSubjectEvents().removeHighlightingFromRows();
	}

	/**
	 * Wybiera w tabeli SE o podanym ID. 
	 * @param id
	 */
	public void setSelectedSubjectEventInTableByID(long id) {
		
//		Planner.log("Schedule.setSelectedSubjectEventInTableByID(): " + "wybieram SE o id " + id);
		
		subjectEventsList.getTableSubjectEvents().setSelectedRowByID(id);
	}
	
	private void runOnRightClick() {
		if (isScheduleViewGroup()) {
			
			long groupID = getFilterPropertyGroupID();
			
			//jesli istnieje przynajmniej jedna subgroup dla aktualnej grupy
			if (CacheService.existsAtLeastOneSubgroupForGivenGroupID(groupID)) {
				CreateSubjectEventDialog csed = new CreateSubjectEventDialog(this, null, null);
				csed.center();
			} else {
				Window.alert("You can't create any subject events until you create at least one subgroup.");
				return;
			}

		}
	}
	
	/**
	 * Zwraca tablice z CalendarDayDTO skojarzonymi z podzialem zajec.
	 * @return
	 */
	public CSCalendarDayDTO[] getCalendarDaysDTOs() {
		CSCalendarDayDTO[] cds = new CSCalendarDayDTO[calendarDays.size()];
		for (int i = 0; i < cds.length; i++) {
			 cds[i] = ((Day)calendarDays.get(i)).getCalendarDayDTO();
		}
		return cds;
	}

	public LecturerPreferences getActiveLecturerPreferences() {
		return activeLecturerPreferences;
	}

	public void setActiveLecturerPreferences(
			LecturerPreferences activeLecturerPreferences) {
		this.activeLecturerPreferences = activeLecturerPreferences;
	}

	
	public boolean isScheduleViewConnectedWithLecturer() {
		if (scheduleView == ScheduleView.LECTURER_PREFERENCES ||
				scheduleView == ScheduleView.LECTURER) {
			return true;
		}
		return false;
	}

	
	public boolean isScheduleViewLecturerPreferences() {
		if (scheduleView == ScheduleView.LECTURER_PREFERENCES) {
			return true;
		}
		return false;
	}
	
	public boolean isScheduleViewGroup() {
		if (scheduleView == ScheduleView.GROUP) {
			return true;
		}
		return false;
	}


	public long getFilterPropertyLecturerID() {
		return filterPropertyLecturerID;
	}

	public void setFilterPropertyLecturerID(long filterPropertyLecturerID) {
		this.filterPropertyLecturerID = filterPropertyLecturerID;
	}

	public long getFilterPropertySemesterID() {
		return filterPropertySemesterID;
	}

	public void setFilterPropertySemesterID(long filterPropertyScheduleID) {
		this.filterPropertySemesterID = filterPropertyScheduleID;
	}

	public boolean isAreShownSubjectEventsHintsForLecturer() {
		return areShownSubjectEventsHintsForLecturer;
	}

	public void setAreShownSubjectEventsHintsForLecturer(
			boolean areShownSubjectEventsHintsForLecturer) {
		this.areShownSubjectEventsHintsForLecturer = areShownSubjectEventsHintsForLecturer;
	}

	public boolean isAreShownSubjectEventsHintsForRoom() {
		return areShownSubjectEventsHintsForRoom;
	}

	public void setAreShownSubjectEventsHintsForRoom(
			boolean areShownSubjectEventsHintsForRoom) {
		this.areShownSubjectEventsHintsForRoom = areShownSubjectEventsHintsForRoom;
	}

	public boolean isAreShownLecturerPreferences() {
		return areShownLecturerPreferences;
	}

	public void setAreShownLecturerPreferences(boolean areShownLecturerPreferences) {
		this.areShownLecturerPreferences = areShownLecturerPreferences;
	}

	public long getFilterPropertyGroupID() {
		return filterPropertyGroupID;
	}

	public void setFilterPropertyGroupID(long filterPropertyGroupID) {
		this.filterPropertyGroupID = filterPropertyGroupID;
	}
	
	/**
	 * pokazuje kontrolke sluzaca do zmiany stanu podzialu (dopiero stworzony, dodano wszystkie se, skonczony)
	 */
	public void showGroupScheduleStateWidget() {
		final SelectBox groupScheduleStateSB = new SelectBox();

		groupScheduleStateSB.addStyleName(STYLE_SCHEDULE_HIDDEN_IN_PRINT);
		
		groupScheduleStateSB.addItem("just created", "0");
		groupScheduleStateSB.addItem("added all subject events", "1");
		groupScheduleStateSB.addItem("finished", "2");

		
		if (filterPropertyGroupID != -1) {
			final CSGroupDTO csGroup = Cache.getCSGroupDTOByID(filterPropertyGroupID);
			
			int scheduleProgress = csGroup.getScheduleProgress().intValue();
			groupScheduleStateSB.setSelectedIndex(scheduleProgress);
			
			groupScheduleStateSB.addChangeListener(new ChangeListener() {
				
				public void onChange(Widget sender) {
					int scheduleState = groupScheduleStateSB.getSelectedIndex();
					csGroup.setScheduleProgress(new Integer(scheduleState));
					AsyncCallback callback = new AsyncCallback() {
						public void onSuccess(Object result) {
							Planner.log("Schedule.showGroupScheduleStateWidget() onSuccess: " + "");
							Cache.saveOrUpdateCSGroup(csGroup);
							
							SchedulesList sl = Planner.get().getSchedulesList();
							
							if (groupScheduleStateSB.getSelectedIndex() == 0) {
								sl.setRedStyleOnGroup(filterPropertyGroupID);
							} else if (groupScheduleStateSB.getSelectedIndex() == 1) {
								sl.setYellowStyleOnGroup(filterPropertyGroupID);
							} else if (groupScheduleStateSB.getSelectedIndex() == 2) {
								sl.setRegularStyleOnGroup(filterPropertyGroupID);
							}
						}
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							Planner.log("Schedule.showGroupScheduleStateWidget() onFailure: " + "");
						}
					};
					
					ServiceHolder.get().saveCSGroup(csGroup, callback);
					
					// TODO dopisac obsluge
					//zapisac 
				}
				
			});
			
		}
		
		
		groupScheduleStateSB.setWidth("180px");
		
		DOM.setStyleAttribute(groupScheduleStateSB.getElement(), "zIndex", "1");
		
		mainAP.add(groupScheduleStateSB, 0, 0);
	}
	
	/**
	 * Pokazuje kontrolke do ustawiania opcji podpowiadania.
	 * @param se
	 */
	public void showSubjectEventEditionWidget(SubjectEvent se) {
		if (displayHintsWidgetDuringSEEdition) {
			seEditionWidgetShowedBeforeMinimize = true;
			showSubjectEventEditionWidgetImpl(se);
		}
	}

	/**
	 * @param se
	 */
	private void showSubjectEventEditionWidgetImpl(SubjectEvent se) {
		if (seEditionWidget == null) {
			
			seEditionWidget = new SubjectEventEditionWidget(se, Schedule.this) {
				@Override
				public void hideWidget() {
					if (seEditionWidget.getSchedule() != null) {
						seEditionWidget.getSchedule().hideSubjectEventEditionWidget();
					} else {
//						SubjectEventEditionWidget.this.hide();
					}
					//super.hideWidget();
				}
			};
			seEditionWidget.setText("Hints");
			
			if (UserSettings.getSeEditionWidgetX() != -1) {
				seEditionWidget.setPopupPosition(UserSettings.getSeEditionWidgetX(), UserSettings.getSeEditionWidgetY());
				seEditionWidget.show();
			} else {
				seEditionWidget.center();
			}
		} else {
			seEditionWidget.setSubjectEvent(se);
			seEditionWidget.applyUserSettingsToSchedule();
		}
	}
	
	
	
	public void hideSubjectEventEditionWidget() {
		seEditionWidgetShowedBeforeMinimize = false;
		hideSubjectEventEditionWidgetImpl();
	}

	/**
	 * 
	 */
	private void hideSubjectEventEditionWidgetImpl() {
		if (seEditionWidget != null) {
			
			//zapisanie informacji o polozeniu okienka
			UserSettings.setSeEditionWidgetX(seEditionWidget.getAbsoluteLeft());
			UserSettings.setSeEditionWidgetY(seEditionWidget.getAbsoluteTop());
			
			seEditionWidget.hide();
			seEditionWidget = null;
//			
//			if (seEditionWidgetDialogBox.isAttached()) {
//			//	seEditionWidgetDialogBox.hide();
//				SubjectEventEditionWidget seew = new SubjectEventEditionWidget(se);
//				
//				//seEditionWidgetDialogBox = new DialogBox(false, false);
//				//seEditionWidgetDialogBox.setText("Tips");
//				seEditionWidgetDialogBox.setWidget(seew);
//				//seEditionWidgetDialogBox.center();
//			}
//			
//		} else {
//			SubjectEventEditionWidget seew = new SubjectEventEditionWidget(se);
//			
//			seEditionWidgetDialogBox = new DialogBox(false, false);
//			seEditionWidgetDialogBox.setText("Tips");
//			seEditionWidgetDialogBox.setWidget(seew);
//			seEditionWidgetDialogBox.center();
		}
	}
	
	public void markAsLoading() {
		if (loader == null) {
			loader = new Loader(LoaderSizes.LOADER_48);
//			kreciolek.setWidth("100px");
//			kreciolek.setHeight("100px");
			
			mainAP.add(loader, 0, 0);
		}
	}
	
	public void markAsLoaded() {
		if (loader != null) {
			mainAP.remove(loader);
		}
	}
	
	public void fixSubjectEventsPositionsInAllDays() {
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			d.fixSubjectEventsPositions();
		}
	}
	
	public void reloadSchedule() {
		markAsLoading();
		removeAllSubectEvents();
		long groupID = getFilterPropertyGroupID();
		long roomID = getFilterPropertyRoomID();
		long lecturerID = getFilterPropertyLecturerID();
//		long semesterID = getFilterPropertySemesterID();
		SchedulesList.downloadCSSubjectEvents(this, new Long(groupID), new Long(roomID), new Long(lecturerID), null);
	}
	
	public void removeAllSubectEvents() {
		for (int i = 0; i < calendarDays.size(); i++) {
			Day d = (Day)calendarDays.get(i);
			d.removeAllSubjectEvents();
		}
	}

	public long getFilterPropertyRoomID() {
		return filterPropertyRoomID;
	}

	public void setFilterPropertyRoomID(long filterPropertyRoomID) {
		this.filterPropertyRoomID = filterPropertyRoomID;
	}
	
	public void onMinimize() {
		if (seEditionWidgetShowedBeforeMinimize) {
			if (seEditionWidget != null) {
				seEditionWidget.hide();
			}
		}
	}
	
	public void onRestore() {
		if (seEditionWidgetShowedBeforeMinimize) {
			if (seEditionWidget != null) {
				seEditionWidget.show();
			}
		}
	}

	public SubjectEventsList getSubjectEventsList() {
		return subjectEventsList;
	}
	
	public void refreshPrintoutScheduleReport() {
		printoutScheduleReport.showDeclarationsSummary(this);
	}
	
	/**
	 * Zwraca liste z referencjami do obiektow CSSubjectEvent skojarzonych
	 * z zalaczonymi do podzialu SubjectEventami (tylko tych, ktore maja ustawiony calendarDay)
	 * @return
	 */
	public List<CSSubjectEventDTO> getAllScheduledSubjectEvents() {
		List<CSSubjectEventDTO> resultList = new ArrayList<CSSubjectEventDTO>();
		
		for (int i = 0; i < calendarDays.size(); i++) {
			
			//dzien
			Day d = (Day)calendarDays.get(i);
			DraggableZone dz = d.getEventsDZ();
			
			for (int j = 0; j < dz.getWidgetCount(); j++) {
				Widget w = dz.getWidget(j);
				if (w instanceof SubjectEvent) {
					SubjectEvent se = (SubjectEvent)w;
					CSSubjectEventDTO csDto = se.getSubjectEventDTO();
					
					resultList.add(csDto);
				}
			}
		}
		
		return resultList;
	}
	
	public void hideHeaderLabelHints() {
		headerLabelHints.addStyleName(STYLE_HIDDEN);
	}

	/**
	 * Pokazuje link Hints.
	 */
	public void showHeaderLabelHints() {
		headerLabelHints.removeStyleName(STYLE_HIDDEN);
	}

	public void setDisplayHintsWidgetDuringSEEdition(
			boolean displayHintsWidgetDuringSEEdition) {
		this.displayHintsWidgetDuringSEEdition = displayHintsWidgetDuringSEEdition;
	}

	public ScheduleView getScheduleView() {
		return scheduleView;
	}

	public void setScheduleView(ScheduleView scheduleView) {
		this.scheduleView = scheduleView;
	}
	
	
	
}
